/**
 * @fileoverview Giant Javascript Framework API.
 * Giant Javascript Framework API HTML编辑器。
 * Copyright (C) 2004-2008 Giant Interective Group, Inc. All rights reserved.
 * 
 * @version 1.0, 2008/11/17
 * @author  Fuchun
 */

/** 编辑器缓存器。*/
var GEditors = window.GEditors = {};

if(typeof giant === 'undefined')
    var giant = {};
if(typeof giant.ui === 'undefined')
    giant.ui = {};

/**
 * 格式化输入框内的数字格式。
 * 
 * @param {HTMLElement} o 输入框对象。
 * @param {Hash} params 参数集。
 */
function GE_formatNumber(o, params) {
    o.value = o.value.replace(/^\s+|\s+$/g, '');
    var num = parseInt(o.value == '' ? 0 : o.value);
    if(num === undefined)
        num = params.defval;
    if(params.max) {
        if(num > params.max)
            num = params.max;
    }
    if(params.min) {
        if(num < params.min)
            num = params.min;
    }
    o.value = num;
}

/**
 * 请求指定用户的相册列表数据时的回调函数。
 * 
 * @param data 相册列表数据。
 */
function GE_parseAlbumJSON(data) {
    var cmbAlbums = $('#cmb_album_list');
    var dataAlbums = data['list'] || [];
    var def = '<option value="0" selected="selected">所有相片</option>';
    if(dataAlbums.length > 0) {
        var buf = [];
        buf.push(def);
        for(var i = 0, len = dataAlbums.length; i < len; i++) {
            buf.push('<option value="' + dataAlbums[i]['id'] + '">' + dataAlbums[i]['name'] + '</option>');
        }
        cmbAlbums.html('');
        $(buf.join('').toString()).appendTo(cmbAlbums);
    } else {
        cmbAlbums.html(def);
    }
    $('#info_loadalbums_status').text(' <--选择相册');
}

/**
 * 请求指定用户的相片列表的回调函数。
 * 
 * @param data 相片列表数据。
 */
function GE_parsePhotosJSON(data, editorId) {
    var photosWrap = $('#edr_photo_list');
    var dataPhotos = data['list'] || [];
    var buf = [];
    for(var i = 0, len = dataPhotos.length; i < len; i++) {
        buf.push('<div class="photo-bd"><span><img alt="' + dataPhotos[i]['photoName'] + '" src="');
        buf.push(Path['userfiles']);
        buf.push(dataPhotos[i]['fileName']);
        buf.push('" onerror="ImageLoad(this, ImageLoad.DEFAULT_IMAGE);" />');
        buf.push('</span></div>');
    }
    buf.push('  <div class="clear"></div>');
    photosWrap.html(buf.join('').toString());
    photosWrap.find('.photo-bd').click(function() {
        if($(this).hasClass('selected')) {
            $(this).removeClass('selected');
            $(this).find('p').remove();
        } else {
            $(this).addClass('selected').append('<p class="selected"></p>');
        }
    });
    var pbuf = [];
    var currPage = data['currPage'], pageSize = data['pageSize'], rCount = data['recordCount'];
    var pageCount = __photoPageCount(rCount, pageSize);
    pbuf.push('<div class="pagee" id="edr_photo_page">');
    for(var i = 1; i <= pageCount; i++) {
        pbuf.push(' ');
        if(i == currPage) {
            pbuf.push('<strong>' + i.toString() + '</strong>');
        } else {
            pbuf.push('<a href="javascript:void(0)" onclick="GEditors[\'');
            pbuf.push(editorId + '\'].getPhotoList(' + i + ');">' + i + '</a>');
        }
    }
    pbuf.push('</div>');
    photosWrap.append(pbuf.join('').toString());
}

function __photoPageCount(count, pagesize) {
    if(count == 0) return 0;
    if(count <= pagesize) return 1;
    if(count % pagesize > 0)
        return parseInt(count / pagesize) + 1;
    else
        return parseInt(count / pagesize);
}

(function($G, $) {
    
    var URL_REGEXP = '^((https?|ftp|rtsp|mms|HTTPS?|FTP|RTSP|MMS)?://)?'
            + '(([0-9a-zA-Z_!~*\'().&=+$%-]+: )?[0-9a-zA-Z_!~*\'().&=+$%-]+@)?'
            + '(([0-9]{1,3}\.){3}[0-9]{1,3}|([0-9a-zA-Z_!~*\'()-]+\.)*'
            + '([0-9a-zA-Z][0-9a-zA-Z]{0,61})?[0-9a-zA-Z]\.[a-zA-Z]{2,6})'
            + '(:[0-9]{1,4})?((/?)|(/[0-9a-zA-Z_!~*\'().;?:@&=+$,%#-]+)+/?)$';
    
    var __ua__ = navigator.userAgent.toLowerCase();
    
    /** 浏览器判定。*/
    var B = {
        version :(__ua__.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/) || [])[1],
        safari :/webkit/.test(__ua__),
        opera :/opera/.test(__ua__),
        msie :/msie/.test(__ua__) && !/opera/.test(__ua__),
        mozilla :/mozilla/.test(__ua__) && !/(compatible|webkit)/.test(__ua__)
    };
    function isURL(str) {
        var urlreg = new RegExp(URL_REGEXP);
        return urlreg.test(str);
    }
    
    function stripTags(str) {
        str = str || '';
        return str.replace(/<\/?[^>]+>/ig, '');
    }
    
    function trim(str) {
        str = str || '';
        return str.replace(/^\s+|\s+$/g, '');
    }
    
    function escapeHTML(str) {
        str = str || '';
        str = str.replace(/&/ig, '&amp;').replace(/</ig, '&lt;').replace(/>/ig, '&gt;');
        str = str.replace(/\"/ig, '&quot;').replace(/\'/ig, '&#39;');
        return str;
    }
    
    function unescapeHTML(str) {
        str = str || '';
        str = str.replace(/&#39;/ig, '\'');
        str = str.replace(/&quot;/ig, '"');
        str = str.replace(/&lt;/ig, '<');
        str = str.replace(/&gt;/ig, '>');
        str = str.replace(/&amp;/ig, '&');
        return str;
    }
    
    function selectText(oInput) {
        if(document.selection) {
            var rg = oInput.createTextRange();
            var sel = rg.duplicate();
            sel.moveStart("character", trim(oInput.value).length);
            sel.setEndPoint("EndToStart", rg);
            sel.select();
        } else {
            oInput.selectionStart = 0;
            oInput.selectionEnd = trim(oInput.value).length;
        }
    }
    
    function buildMediaPlayer(params) {
        var buf = new StringBuilder();
        buf.append('<object width="').append(params.w).append('" height="').append(params.h).append('" ');
        buf.append('border="0" align="baseline" type="application/x-oleobject" standy="Loading ');
        buf.append('Micorsoft Windows Media Player components..." codebase="http://activex.microsoft');
        buf.append('.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=6,4,7,1112" classid="CLSID:');
        buf.append('6BF52A52-394A-11d3-B153-00C04F79FAA6" id="MediaPlayer_').append(params.id).append('" ');
        buf.append('name="MediaPlayer_').append(params.id).append('" style="display:block;margin:0 auto 10px;">');
        buf.append('  <param name="URL" value="').append(params.src).append('" />');
        buf.append('  <param name="autoStart" value="').append(params.autoStart).append('" />');
        buf.append('  <param name="invokeURLs" value="false" />');
        buf.append('  <param name="playCount" value="100" />');
        buf.append('  <param name="defaultFrame" value="datawindow" />');
        buf.append('  <param name="showDisplay" value="true" />');
        buf.append('  <param name="allowScan" value="true" />');
        buf.append('  <embed width="').append(params.w).append('" height="').append(params.h).append('" ');
        buf.append(' invokeurls="0" clicktoplay="0" ');
        buf.append('enablecontextmenu="1" allowscan="1" transparentatstart="0" animationatstart="0" ');
        buf.append('autorewind="0" autostart="').append(params.autoStart ? '1' : '0').append('" showcaptioning="0" ');
        buf.append('showgotobar="0" autosize="0" showstatusbar="1" showdisplay="0" showtracker="1" ');
        buf.append('showaudiocontrols="1" showpositioncontrols="0" showcontrols="1" id="MediaPlayer_').append(params.id).append('" ');
        buf.append('name="MediaPlayer_').append(params.id).append('" pluginspage="" type="application/x-mplayer2" ');
        buf.append('src="').append(params.src).append('" style="display:block;margin:0 auto 10px;" />');
        buf.append('</object>');
        return buf.toString();
    }
    
    function buildFlashPlayer(params) {
        var buf = new StringBuilder();
        buf.append('<embed width="').append(params.w).append('" height="').append(params.h).append('" ');
        buf.append('quality="high" name="" pluginspage="http://www.macromedia.com/go/getflashplayer" ');
        buf.append('type="application/x-shockwave-flash" ');
        buf.append('src="').append(params.src).append('" wmode="transparent" style="');
        buf.append('display:block;margin:0 auto 10px;" />');
        return buf.toString();
    }
    
    var _editorSettings = {
        root: Path['static'],
        id: 'geditor',
        name: 'content',
        size: [500, 300],
        toolbarConfig: {
            bold: false,
            italic: false,
            underline: false,
            left: false,
            center: false,
            right: false,
            font: false,
            fontSize: false,
            color: false,
            image: false,
            link: false,
            media: false,
            face: true
        },
        currentUid: '',
        canUploadImage: false,
        canUploadMedia: false,
        uploadImageURL: Path.domain + "/album/ajaxUploadImage.action",
        // 请求获得指定用户的相册列表数据的服务器地址
        albumImageURL: Path.domain + '/album/ajaxloadAlbumList.action',
        // 请求获得指定用户的相册的相片数据的服务器地址
        photoImageURL: Path.domain + '/album/ajaxloadPhotoList.action',
        uploadMediaURL: ""
    };
    
    var FONTS = ['宋体', '隶书', '黑体', '幼圆', '楷体_GB2312', 'Arial', 'Tahoma', 'Verdana',
                 'Times New Roman', 'Courier New', 'Sans-serif'];

    var FONT_SIZE = ['10', '14', '16', '18', '24', '32', '48'];
    
    var COLORS = [
        "#333333", "#000000", "#993300", "#333300", "#003300", "#003366", "#000080", "#333399",
        "#808080", "#800000", "#ff6600", "#808000", "#008000", "#008080", "#0000ff", "#666699",
        "#999999", "#ff0000", "#ff9900", "#99cc00", "#339966", "#33cccc", "#3366ff", "#800080",
        "#c0c0c0", "#ff00ff", "#ffcc00", "#ffff00", "#00ff00", "#00ffff", "#00ccff", "#993366",
        "#ffffff", "#ff99cc", "#ffcc99", "#ffff99", "#ccffcc", "#F4F9FD", "#99ccff", "#cc99ff"
    ];

    var FACES = [
        "惊讶", "撇嘴", "色", "发呆", "得意", "伤心啊", "害羞死了", "闭嘴",
        "睡觉了", "大哭", "好尴尬哦", "我怒了", "调皮", "呲牙咧嘴", "微笑", "难过",
        "酷", "无语", "抓狂", "我吐", "偷笑", "可爱", "白眼", "我骄傲",
        "我饿了", "困了", "惊恐", "汗", "憨笑", "大兵", "奋斗", "咒骂",
        "疑问", "嘘", "晕", "折磨", "敲打", "拜拜", "大便", "玫瑰",
        "玫瑰调谢了", "吻", "爱心", "心碎了", "我顶", "鄙视", "握手", "胜利"
    ];
    
    /**
     * @class
     * 
     * @constructor
     * @param {Hash} s 编辑器的参数集。
     * @returns {giant.ui.Editor}
     */
    giant.ui.Editor = function(s) {
        s = giant.extend(_editorSettings, s,true);
        this.path = s['root'] || _editorSettings.root;
        this.width = typeof s['width'] == 'undefined' ? ( typeof s['size'] == 'undefined' ?
                _editorSettings.size[0] : s['size'][0]) : s['width'];
        this.height = typeof s['height'] == 'undefined' ? ( typeof s['size'] == 'undefined' ?
                _editorSettings.size[1] : s['size'][1]) : s['height'];
        this.toolbarConfig = s['toolbarConfig'] || _editorSettings.toolbarConfig;
        this.canUploadImage = s['canUploadImage'] || _editorSettings.canUploadImage;
        this.canUploadMedia = s['canUploadMedia'] || _editorSettings.canUploadMedia;
        this.uploadImageURL = s['uploadImageURL'] || _editorSettings.uploadImageURL;
        this.container = s['id'] || _editorSettings.id;
        this.jquery_container = '#' + this.container;
        this.editorId = (s['id'] || _editorSettings.id) + '_id';
        this.editorName = s['name'] || _editorSettings.name;
        // Opera Browser
        this.textarea = null;
        this.iframe = null;
        // 选择的范围
        this.range = null;
        // 选择的类型
        this.seltype = null;
        // 打开的工具栏Panel的容器Id
        this.panelId = 'edp';
        // 当前显示的Panel ID
        this.currPanel = '';
        
        this.currentUid = s['currentUid'] || _editorSettings.currentUid;
        this.albumImageURL = s['albumImageURL'] || _editorSettings.albumImageURL;
        this.photoImageURL = s['photoImageURL'] || _editorSettings.photoImageURL;
        
        this._toolbarId = (s['id'] || _editorSettings.id) + '_tbr';
        this._framedivId = (s['id'] || _editorSettings.id) + '_efr';
        this._frameId = (s['id'] || _editorSettings.id) + '_frame';
        this._facePath = Path['images'] + '/images/face/zhengtu/';
        this._currentTool = '';
        GEditors[s['id']]=this;
    };
    
    giant.ui.Editor.get = function(s) {
        if(GEditors[s.id]) {
            return GEditors[s.id];
        }
        GEditors[s.id] = new giant.ui.Editor(s);
        return GEditors[s.id];
    };
    
    giant.ui.Editor.prototype = {
            
        /**
         * 初始化后显示编辑器。
         */
        init: function(str) {
            this.drawEditor();
            this.initObjects();
            if(B.msie)
                str = str || '';
            else
                str = str || '<br _moz_dirty=""/>';
            if(B.opera) {
                this.textarea.value = str;
                return;
            }
            this.doc().designMode = "On";
            this.doc().contentEditable = true;
            this.doc().open();
            this.doc().writeln(this.getFrameInner(str));
            this.doc().close();
            return this;
        },
        
        doc: function() {
//            var doc = $B.msie ? giant.E(this._frameId).contentWindow.document :
//                    window.frames[this._frameId].document;
            var doc = giant.E(this._frameId).contentWindow.document;
            return doc;
        },
        
        /** 清空编辑器的内容。*/
        clear: function() {
            if(B.opera)
                this.textarea.value = '';
            else
                this.doc().body.innerHTML = '';
        },
        
        /** 返回编辑器中的内容。*/
        getText: function() {
            if(B.opera) {
                return trim(this.textarea.value);
            } else if(B.msie && B.version > 6) {
                return trim(this.doc().body.innerText);
            } else {
                return stripTags(trim(this.doc().body.innerHTML));
            }
        },
        
        /** 返回编辑器中的内容（该内容包含Html代码）。*/
        getHtml: function() {
            if(B.opera)
                return escapeHTML(trim(this.textarea.value));
            else {
                var inhtml = trim(this.doc().body.innerHTML);
                // 检查是否已输入内容
                var tmp = inhtml.replace(/<p>&nbsp;<\/p>/ig, '').replace(/<br[^>]*>/ig, '');
                tmp = tmp.replace(/(&nbsp;)*/ig, '');
                if(trim(tmp) == '')
                    return '';
                inhtml = inhtml.replace(/<img([^>]*)\/?>/ig, '<img$1 />');
                // 去除　style　样式标签
                inhtml = inhtml.replace(/<style[^>]*>([\S\s]*?)<\/style>/igm, '');
                // 去除　script 脚本标签
                inhtml = inhtml.replace(/<script[^>]*>([\S\s]*?)<\/script>/igm, '');
                // 去除　meta 标签
                inhtml = inhtml.replace(/<meta[^>]*>/ig, '');
                // 去除　内容尾部的连续换行和空白段落
                inhtml = inhtml.replace(/(<br[^>]*>)*$/ig, '');
                inhtml = inhtml.replace(/([\s]*<p[^>]*>(&nbsp;)*<\/p>)*$/ig, '');
                return this._parseHtml(inhtml);
            }
        },
        
        // 解析并标准化内容中的Html标签
        _parseHtml: function(shtml) {
            if(shtml == '')
                return '';
            shtml = shtml.replace(/(<br[^>]*>)/ig, '<br />');
            return shtml;
        },
        
        /** 设置编辑器中的内容（该内容包含Html代码）。*/
        setHtml: function(shtml) {
            if(B.opera)
                this.textarea.value = unescapeHTML(shtml);
            else {
                this.doc().body.innerHTML = trim(shtml);
            }
        },
        
        /**
         * 初始化编辑器内部各个变量。
         */
        initObjects: function() {
            if(B.opera)
                this.textarea = $('#' + this.editorId);
            else
                this.iframe = window.frames[this._frameId];
        },
        
        /** 初始化Frame内的Html内容。*/
        getFrameInner: function(innerHtml) {
            innerHtml = innerHtml || '';
            var buf = new StringBuilder();
            buf.append('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ');
            buf.append('"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">');
            buf.append('<html xmlns="http://www.w3.org/1999/xhtml">');
            buf.append('<head>');
            buf.append('<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />');
            buf.append('<title></title>');
            buf.append('<style type="text/css">');
            buf.append('body {background-color:#FFFFFF;margin:0px;padding:0px;overflow:hidden;overfow-y:auto;overflow-x:auto;"}');
            buf.append('p {line-height:150%;margin:0;padding:0;}');
            buf.append('.edr-img {margin:3px 0 2px;}');
            buf.append('</style>');
            buf.append('</head>');
            buf.append('<body>').append(innerHtml).append('</body>');
            buf.append('</html>');
            return buf.toString();
        },
            
        drawEditor: function() {
            var buf = new StringBuilder();
            if(B.opera) {
                buf.append('<textarea id="').append(this.editorId).append('" name="');
                buf.append(this.editorName).append('" style="width:').append(this.width).append('px;');
                buf.append('height:').append(this.height).append('px"></textarea>');
            } else {
                buf.append('<div class="edr">\n');
                buf.append('  <div class="tbr" id="').append(this._toolbarId).append('">\n');
                if(this.toolbarConfig.font) {
                    buf.append('  <a id="tbr_fontname" href="javascript:void(0)" title="字体设置" onclick="');
                    buf.append('GEditors[\'').append(this.container).append('\'].fontPanel(this);return false;"><span class="font">&nbsp;</span></a>\n');
                }
                if(this.toolbarConfig.fontSize) {
                    buf.append('  <a id="tbr_fontsize" href="javascript:void(0)" title="字体大小" onclick="');
                    buf.append('GEditors[\'').append(this.container).append('\'].fontSizePanel(this);return false;"><span class="fontsize">&nbsp;</span></a>\n');
                }
                if(this.toolbarConfig.color) {
                    buf.append('  <a id="tbr_forecolor" href="javascript:void(0)" title="字体颜色" onclick="');
                    buf.append('GEditors[\'').append(this.container).append('\'].colorPanel(this);return false;"><span class="color">&nbsp;</span></a>\n');
                }
                if(this.toolbarConfig.left) {
                    buf.append('  <a id="tbr_left" href="javascript:void(0)" title="居左" onclick="');
                    buf.append('GEditors[\'').append(this.container).append('\'].setStyle(\'justifyLeft\');return false;"><span class="left">&nbsp;</span></a>\n');
                }
                if(this.toolbarConfig.center) {
                    buf.append('  <a id="tbr_center" href="javascript:void(0)" title="居中" onclick="');
                    buf.append('GEditors[\'').append(this.container).append('\'].setStyle(\'justifyCenter\');return false;"><span class="center">&nbsp;</span></a>\n');
                }
                if(this.toolbarConfig.right) {
                    buf.append('  <a id="tbr_right" href="javascript:void(0)" title="居右" onclick="');
                    buf.append('GEditors[\'').append(this.container).append('\'].setStyle(\'justifyRight\');return false;"><span class="right">&nbsp;</span></a>\n');
                }
                if(this.toolbarConfig.bold) {
                    buf.append('  <a id="tbr_bold" href="javascript:void(0)" title="粗体" onclick="');
                    buf.append('GEditors[\'').append(this.container).append('\'].setStyle(\'bold\');return false;"><span class="bold">&nbsp;</span></a>\n');
                }
                if(this.toolbarConfig.italic) {
                    buf.append('  <a id="tbr_italic" href="javascript:void(0)" title="斜体" onclick="');
                    buf.append('GEditors[\'').append(this.container).append('\'].setStyle(\'italic\');return false;"><span class="italic">&nbsp;</span></a>\n');
                }
                if(this.toolbarConfig.underline) {
                    buf.append('  <a id="tbr_underline" href="javascript:void(0)" title="下划线" onclick="');
                    buf.append('GEditors[\'').append(this.container).append('\'].setStyle(\'underline\');return false;"><span class="underline">&nbsp;</span></a>\n');
                }
                if(this.toolbarConfig.image) {
                    buf.append('  <a id="tbr_image" href="javascript:void(0)" title="插入图片" onclick="');
                    buf.append('GEditors[\'').append(this.container).append('\'].imagePanel(this);return false;"><span class="image">&nbsp;</span></a>\n');
                }
                if(this.toolbarConfig.media) {
                    buf.append('  <a id="tbr_media" href="javascript:void(0)" title="插入媒体" onclick="');
                    buf.append('GEditors[\'').append(this.container).append('\'].mediaPanel(this);return false;"><span class="media">&nbsp;</span></a>\n');
                }
                if(this.toolbarConfig.link) {
                    buf.append('  <a id="tbr_link" href="javascript:void(0)" title="超链接" onclick="');
                    buf.append('GEditors[\'').append(this.container).append('\'].linkPanel(this);return false;"><span class="link">&nbsp;</span></a>\n');
                }
                if(this.toolbarConfig.face) {
                    buf.append('  <a id="tbr_face" href="javascript:void(0)" title="表情" onclick="');
                    buf.append('GEditors[\'').append(this.container).append('\'].facePanel(this);return false;"><span class="face">&nbsp;</span></a>\n');
                }
                buf.append('  <div class="clear"></div>\n');
                buf.append('  </div>\n');
                buf.append('  <div class="efr" id="').append(this._framedivId).append('">\n');
                buf.append('    <iframe id="').append(this._frameId).append('" name="').append(this._frameId).append('"');
                buf.append(' frameborder="0" marginwidth="0" scrolling="auto" src="" width="').append(this.width).append('" height="');
                buf.append(this.height).append('" onfocus="GEditors[\'').append(this.container).append('\'].iframeOnFocus();" ');
                buf.append('onblur="GEditors[\'').append(this.container).append('\'].iframeOnBlur();"></iframe>');
                buf.append('  </div>\n');
                buf.append('</div>\n');
            }
            $(this.jquery_container).html(buf.toString());
        },
        
        /** Iframe的聚焦事件函数。*/
        iframeOnFocus: function() {
            $('#' + this._framedivId).css({borderTopColor:'#666',borderLeftColor:'#666'});
        },
        
        /** Iframe的失去聚焦事件函数。*/
        iframeOnBlur: function() {
            $('#' + this._framedivId).css({borderTopColor:'#ccc',borderLeftColor:'#ccc'});
        },
        
        /** 初始化选择的范围。*/
        beginSelection: function() {
            this.iframe.focus();
            if(document.selection) {
                this.range = this.doc().selection.createRange();
                this.seltype = this.doc().selection.type;
            }
        },
        
        /** 设置样式。*/
        setStyle: function(name, value) {
            if(document.selection) { // IE
                if(!this.range)
                    this.beginSelection();
                if(this.range && this.seltype != 'Control' && this.range.text != '') {
                    this.range.execCommand(name, false, value);
                    this.range.select();
                } else {
                    this.doc().execCommand(name, false, value);
                }
                this.range = null;
            } else {
                this.doc().execCommand(name, false, value);
                giant.E(this._frameId).contentWindow.focus();
            }
            this.closePanel(this.currPanel);
            this.closePanel(this.panelId + '_' + name);
        },
        
        /** 在插入点插入一段Html。*/
        insertHTML: function(shtml) {
            if(document.selection) { // IE
                if(!this.range) {
                    this.beginSelection();
                }
                if(this.range && this.seltype != "Control") {
                    this.range.pasteHTML(shtml);
                    this.range.select();
                }
                this.range = null;
            } else {
                this.doc().execCommand('insertHTML', false, shtml);
                giant.E(this._frameId).contentWindow.focus();
            }
            this.closePanel(this.currPanel);
        },
        
        /** 面板的显示控制。*/
        togglePanel: function(o, panel, panelPos, callback) {
            if(panel.css('display') == 'none') {
                $('.edr-panel').hide('fast');
                this.currPanel = panel.attr('id');
                panel.show('fast');
                giant.dom.xy(panel[0], panelPos, callback);
                if(this._currentTool !== '')
                    $('#' + this._currentTool).removeClass('selected');
                $(o).addClass('selected');
                this._currentTool = o.id;
            } else {
                $('.edr-panel').hide('fast');
                $(o).removeClass('selected');
                this._currentTool = '';
            }
        },
        
        /** 关闭工具栏面板。*/
        closePanel: function(id, callback) {
            if($('#' + id).length > 0) {
                if(giant.isFunction(callback))
                    callback.call(this);
                $('#' + id).hide('fast');
                var tid = 'tbr_' + id.replace(new RegExp(this.panelId), '');
                $('#' + tid).removeClass('selected');
                if(this._currentTool !== '')
                    $('#' + this._currentTool).removeClass('selected');
            }
        },
        
        /** 打开字体选择面板。*/
        fontPanel: function(o) {
            this.beginSelection();
            var font_panel_id = this.panelId + o.id.replace(/tbr/i, '');
            var font_panel = $('#' + font_panel_id);
            var oPos = giant.dom.xy(o);
            var oSize = [o.offsetWidth, o.offsetHeight];
            if(font_panel.length == 0) {
                var buf = new StringBuilder();
                buf.append('<div class="edr-panel ft-panel" id="').append(font_panel_id).append('"');
                buf.append(' style="width:150px;display:none;">\n');
                var ft_s = '';
                for(var i = 0, len = FONTS.length; i < len; i++) {
                    ft_s = i > 8 ? 'ft' + (i + 1) : 'ft0' + (i + 1);
                    buf.append('<a class="').append(ft_s).append('" href="javascript:void(0)" ');
                    buf.append('onclick="GEditors[\'').append(this.container).append('\'].');
                    buf.append('setStyle(\'fontname\', \'').append(FONTS[i]).append('\');return false;">');
                    buf.append(FONTS[i]).append('</a>\n');
                }
                buf.append('</div>\n');
                $(buf.toString()).appendTo('body')[0];
                font_panel = $('#' + font_panel_id);
                this.togglePanel(o, font_panel, [oPos[0] + 5, oPos[1] + oSize[1] + 5]);
            } else
                this.togglePanel(o, font_panel, [oPos[0] + 5, oPos[1] + oSize[1] + 5]);
        },
        
        /** 打开字体大小选择面板。*/
        fontSizePanel: function(o) {
            this.beginSelection();
            var fs_panel_id = this.panelId + o.id.replace(/tbr/i, '');
            var fs_panel = $('#' + fs_panel_id);
            var oPos = giant.dom.xy(o);
            var oSize = [o.offsetWidth, o.offsetHeight];
            if(fs_panel.length == 0) {
                var buf = new StringBuilder();
                buf.append('<div class="edr-panel fs-panel" id="').append(fs_panel_id).append('"');
                buf.append(' style="width:260px;display:none;">\n');
                var fs_s = '';
                for(var i = 0, len = FONT_SIZE.length; i < len; i++) {
                    fs_s = 'fs' + FONT_SIZE[i];
                    buf.append('<a class="').append(fs_s).append('" href="javascript:void(0)" ');
                    buf.append('onclick="GEditors[\'').append(this.container).append('\'].');
                    buf.append('setStyle(\'fontsize\', \'').append(i + 1).append('\');return false;">');
                    buf.append('字体大小</a>\n');
                }
                buf.append('</div>\n');
                $(buf.toString()).appendTo('body')[0];
                fs_panel = $('#' + fs_panel_id);
                this.togglePanel(o, fs_panel, [oPos[0] + 5, oPos[1] + oSize[1] + 5]);
            } else
                this.togglePanel(o, fs_panel, [oPos[0] + 5, oPos[1] + oSize[1] + 5]);
        },
        
        /** 打开字体颜色选择面板。*/
        colorPanel: function(o) {
            this.beginSelection();
            var col_panel_id = this.panelId + o.id.replace(/tbr/i, '');
            var col_panel = $('#' + col_panel_id);
            var oPos = giant.dom.xy(o);
            var oSize = [o.offsetWidth, o.offsetHeight];
            if(col_panel.length == 0) {
                var buf = new StringBuilder();
                buf.append('<div class="edr-panel col-panel" id="').append(col_panel_id).append('"');
                buf.append(' style="display:none;">\n');
                for(var i = 0, len = COLORS.length; i < len; i++) {
                    buf.append('<a id="color_').append(COLORS[i].replace(/#/ig, '')).append('" style="background-color:');
                    buf.append(COLORS[i]).append(';" ').append('title="').append(COLORS[i]).append('" href="javascript:void(0)" ');
                    buf.append('onclick="GEditors[\'').append(this.container).append('\'].');
                    buf.append('setStyle(\'forecolor\', \'').append(COLORS[i]).append('\');return false;">&nbsp;&nbsp;&nbsp;</a>\n');
                }
                buf.append('<div class="clear"></div>\n');
                buf.append('</div>\n');
                $(buf.toString()).appendTo('body')[0];
                col_panel = $('#' + col_panel_id);
                this.togglePanel(o, col_panel, [oPos[0] + 5, oPos[1] + oSize[1] + 5]);
            } else
                this.togglePanel(o, col_panel, [oPos[0] + 5, oPos[1] + oSize[1] + 5]);
        },
        
        _mediaCurrTag: 'flash',
        
        /** 媒体面板标签点击事件。*/
        mediaTagClick: function(o, callback) {
            if($(o).hasClass('selected'))
                return;
            var tagsign = o.id.replace(/_tag/ig, '');
            $('#' + this._mediaCurrTag + '_media_wrap').css('display', 'none');
            $('#' + this._mediaCurrTag + '_tag').removeClass('selected');
            $(o).addClass('selected');
            $('#' + tagsign + '_media_wrap').css('display', 'block');
            this._mediaCurrTag = tagsign;
            //if(tagsign == 'flash')
            //    $('#' + tagsign + '_media_wrap').find('input[name=netImageUrl]').focus();
            if(giant.isFunction(callback))
                callback.call(this);
        },
        
        /** 插入媒体播放器。*/
        insertMediaPlayer: function(o, formId) {
            $(o).attr('disabled', 'disabled');
            var form = $('#' + formId);
            if(form.length > 0) {
                var osrc = form[0].src, ow = form[0].w, oh = form[0].h, oauto = form[0].autoStart;
                if(!osrc.value.endsWith('.mp3') && !osrc.value.endsWith('.wav') && !osrc.value.endsWith('.wma')
                        && !osrc.value.endsWith('.mpeg') && !osrc.value.endsWith('.asf')) {
                    alert('目前支持的媒体文件格式有：mp3、wav、wma、mpeg、asf，请确认您输入的媒体文件地址格式是否正确！');
                    $(o).removeAttr('disabled');
                    selectText(osrc);
                    return;
                }
                GE_formatNumber(ow, {min:350, max:500, defval:350});
                GE_formatNumber(oh, {min:64, max:500, defval:64});
                var params = {
                    src: osrc.value,
                    w: ow.value,
                    h: oh.value,
                    autoStart: oauto.checked ? 'true' : 'false'
                };
                params.id = this.container + Math.random();
                if(osrc.value.endsWith('.mp3') || osrc.value.endsWith('.wma'))
                    params.h = 64;
                var mediaplayer = buildMediaPlayer(params);
                this.insertHTML(mediaplayer);
                $(o).removeAttr('disabled');
            }
        },
        
        /** 插入Flash。*/
        insertFlashPlayer: function(o, formId) {
            $(o).attr('disabled', 'disabled');
            var form = $('#' + formId);
            if(form.length > 0) {
                var osrc = form[0].src, ow = form[0].w, oh = form[0].h;
                if(!osrc.value.endsWith('.swf')) {
                    alert('请确认您输入的Flash文件地址格式是否正确！');
                    $(o).removeAttr('disabled');
                    selectText(osrc);
                    return;
                }
                GE_formatNumber(ow, {min:200, max:640, defval:480});
                GE_formatNumber(oh, {min:200, max:640, defval:400});
                var params = {
                    src: osrc.value,
                    w: ow.value,
                    h: oh.value
                };
                var fplayer = buildFlashPlayer(params);
                this.insertHTML(fplayer);
                $(o).removeAttr('disabled');
            }
        },
        
        /** 关闭媒本面板。*/
        closeMediaPanel: function(o, formId) {
            var form = $('#' + formId);
            try {
                form.resetForm();
            } catch(e) {}
            var panel = $(o).parents('.edr-panel');
            panel.hide('fast');
            $('#tbr' + panel.attr('id').replace(new RegExp(this.panelId),'')).removeClass('selected');
        },
        
        /** 打开其他媒体标签面板。*/
        otherMediaPanel: function() {
            var other = $('#other_media_wrap');
            if(trim(other.html()) == '') {
                var buf = new StringBuilder();
                buf.append('<form id="form_add_media" name="formAddMedia" method="post" ');
                buf.append('action="').append(location.href).append('">');
                buf.append('<div class="edr-img-error" id="add_media_error">支持的媒体文件格式：mp3、wav、wma、mpeg、asf</div>');
                buf.append('<table cellspacing="0"><tr>');
                buf.append('  <td width="100" height="30" align="right">媒体文件地址：</td>');
                buf.append('  <td width="210"><input type="text" class="txt w200" name="src" ');
                buf.append('value="http://" /></td>');
                buf.append('</tr><tr>');
                buf.append('  <td height="30" align="right">播放器宽度：</td>');
                buf.append('  <td><input type="text" class="txt w50" name="w" maxlength="3" value="350" ');
                buf.append('onkeyup="this.value=this.value.replace(/\\D/ig, \'\');" onblur="');
                buf.append('GE_formatNumber(this, {min:350, max:500, defval:350});" /></td>');
                buf.append('</tr><tr>');
                buf.append('  <td height="30" align="right">播放器高度：</td>');
                buf.append('  <td><input type="text" class="txt w50" name="h" maxlength="3" value="64" ');
                buf.append('onkeyup="this.value=this.value.replace(/\\D/ig, \'\');" onblur="');
                buf.append('GE_formatNumber(this, {min:64, max:500, defval:64});" /></td>');
                buf.append('</tr><tr>');
                buf.append('  <td height="30" align="right">参数设置：</td>');
                buf.append('  <td><input type="checkbox" id="other_media_autostart" name="autoStart" value="true" />&nbsp;');
                buf.append('<label for="other_media_autostart">是否自动播放</label></td>');
                buf.append('</tr><tr>');
                buf.append('  <td height="40">&nbsp;</td>');
                buf.append('  <td><input type="button" class="btn btnmain" value="确&nbsp;&nbsp;定" onclick="');
                buf.append('GEditors[\'').append(this.container).append('\'].insertMediaPlayer(this, \'form_add_media\');" />&nbsp;');
                buf.append('&nbsp;<input type="button" class="btn btnsubm" value="取&nbsp;&nbsp;消" onclick="');
                buf.append('GEditors[\'').append(this.container).append('\'].closeMediaPanel(this, \'form_add_media\');" /></td>');
                buf.append('</tr></table></form>');
                other.html(buf.toString());
            }
            var form = $('#form_add_media');
            selectText(form[0].src);
        },
        
        /** 找开媒本文本面板。*/
        mediaPanel: function(o) {
            this.beginSelection();
            var media_panel_id = this.panelId + o.id.replace(/tbr/i, '');
            var media_panel = $('#' + media_panel_id);
            var oPos = giant.dom.xy(o);
            var oSize = [o.offsetWidth, o.offsetHeight];
            if(media_panel.length == 0) {
                var $self = this;
                var f = function() {
                    var wrap = $('#flash_media_wrap');
                    if(trim(wrap.html()) == '') {
                        var b = new StringBuilder();
                        b.append('<form id="form_add_flash" name="formAddFlash" method="post" ');
                        b.append('action="').append(location.href).append('" onsubmit="return false;">');
                        b.append('<table cellspacing="0"><tr>');
                        b.append('  <td width="100" height="30" align="right">Flash文件地址：</td>');
                        b.append('  <td width="210"><input type="text" class="txt w200" name="src" ');
                        b.append('value="http://" /></td>');
                        b.append('</tr><tr>');
                        b.append('  <td height="30" align="right">播放器宽度：</td>');
                        b.append('  <td><input type="text" class="txt w50" name="w" maxlength="3" value="480" ');
                        b.append('onkeyup="this.value=this.value.replace(/\\D/ig, \'\');" onblur="');
                        b.append('GE_formatNumber(this, {min:200, max:640, defval:480});" /></td>');
                        b.append('</tr><tr>');
                        b.append('  <td height="30" align="right">播放器高度：</td>');
                        b.append('  <td><input type="text" class="txt w50" name="h" maxlength="3" value="400" ');
                        b.append('onkeyup="this.value=this.value.replace(/\\D/ig, \'\');" onblur="');
                        b.append('GE_formatNumber(this, {min:200, max:640, defval:400});" /></td>');
                        b.append('</tr><tr>');
                        b.append('  <td height="40">&nbsp;</td>');
                        b.append('  <td><input type="button" class="btn btnmain" value="确&nbsp;&nbsp;定" onclick="');
                        b.append('GEditors[\'').append($self.container).append('\'].insertFlashPlayer(this, \'form_add_flash\');" />&nbsp;');
                        b.append('&nbsp;<input type="button" class="btn btnsubm" value="取&nbsp;&nbsp;消" onclick="');
                        b.append('GEditors[\'').append($self.container).append('\'].closeMediaPanel(this, \'form_add_flash\');" /></td>');
                        b.append('</tr></table></form>');
                        wrap.html(b.toString());
                    }
                    var form = $('#form_add_flash');
                    selectText(form[0].src);
                };
                var buf = new StringBuilder();
                buf.append('<div class="edr-panel media-panel" id="').append(media_panel_id).append('" ');
                buf.append('style="display:none;">\n');
                buf.append('  <div class="menu"><ul>\n');
                buf.append('  <li class="flash selected" id="flash_tag" ');
                buf.append('onclick="GEditors[\'').append(this.container).append('\'].mediaTagClick(this);">Flash</li>\n');
                buf.append('  <li class="media" id="other_tag" ');
                buf.append('onclick="GEditors[\'').append(this.container).append('\'].mediaTagClick(this, GEditors[\'');
                buf.append(this.container).append('\'].otherMediaPanel);">其他媒体</li>\n');
                buf.append('  <a href="javascript:void(0)" class="close" onclick="GEditors[\'').append(this.container);
                buf.append('\'].closeImagePanel(\'').append(media_panel_id).append('\');return false;">关闭×</a>\n');
                buf.append('  </ul></div>\n');
                buf.append('<div class="edr-media-wrap" id="flash_media_wrap"></div>');
                buf.append('<div class="edr-media-wrap" id="other_media_wrap" style="display:none;"></div>');
                buf.append('<div class="clear"></div>\n');
                buf.append('</div>\n');
                $(buf.toString()).appendTo('body')[0];
                media_panel = $('#' + media_panel_id);
                this.togglePanel(o, media_panel, [oPos[0] + 5, oPos[1] + oSize[1] + 5], f);
            } else
                this.togglePanel(o, media_panel, [oPos[0] + 5, oPos[1] + oSize[1] + 5]);
        },
        
        /** 打开链接面板。*/
        linkPanel: function(o) {
            this.beginSelection();
            var lnk_panel_id = this.panelId + o.id.replace(/tbr/i, '');
            var lnk_panel = $('#' + lnk_panel_id);
            var oPos = giant.dom.xy(o);
            var oSize = [o.offsetWidth, o.offsetHeight];
            var f = function() {
                $(this).find('input[name=lnkName]').focus();
            };
            if(lnk_panel.length == 0) {
                var buf = new StringBuilder();
                buf.append('<div class="edr-panel lnk-panel" id="').append(lnk_panel_id).append('" ');
                buf.append('style="display:none;">\n');
                buf.append('<form id="form_add_lnk" name="formAddLnk" onsubmit="return false;" method="post" ');
                buf.append('action="').append(location.href).append('">');
                buf.append('<table cellspacing="0"><tr>');
                buf.append('  <td width="60" height="30" align="right">链接文字：</td>');
                buf.append('  <td width="310"><input type="text" class="txt w300" name="lnkName" ');
                buf.append('value="请输入链接文字" onfocus="if(this.value==\'请输入链接文字\')this.value=\'\';" ');
                buf.append('onblur="if(this.value==\'\')this.value=\'请输入链接文字\';"/></td>');
                buf.append('</tr><tr>');
                buf.append('  <td height="30" align="right">链接地址：</td>');
                buf.append('  <td><input type="text" class="txt w300" name="lnkUrl" value="http://" /></td>');
                buf.append('</tr><tr>');
                buf.append('  <td height="30" colspan="2" align="center"><input type="button" ');
                buf.append('class="btn btnmain" value="确&nbsp;&nbsp;定" onclick="GEditors[\'');
                buf.append(this.container).append('\'].insertLink(this, \'form_add_lnk\');" />&nbsp;&nbsp;&nbsp;');
                buf.append('<input type="button" class="btn btnmain" value="取&nbsp;&nbsp;消" onclick="GEditors[\'');
                buf.append(this.container).append('\'].closePanel(\'').append(lnk_panel_id).append('\');" /></td>');
                buf.append('</tr></table>');
                buf.append('</form>');
                buf.append('<div class="clear"></div>\n');
                buf.append('</div>\n');
                $(buf.toString()).appendTo('body')[0];
                lnk_panel = $('#' + lnk_panel_id);
                this.togglePanel(o, lnk_panel, [oPos[0] + 5, oPos[1] + oSize[1] + 5], f);
            } else
                this.togglePanel(o, lnk_panel, [oPos[0] + 5, oPos[1] + oSize[1] + 5], f);
        },
        
        /** 插入链接地址。*/
        insertLink: function(o, formId) {
            var form = $('#' + formId);
            var url = form[0].lnkUrl;
            var urlInfo = form[0].lnkName;
            var urlval = trim(url.value);
            if(!isURL(urlval)) {
                alert('请输入链接地址！');
                url.focus();
                selectText(url);
                return;
            }
            var urlInfoval = trim(urlInfo.value);
            if(urlInfoval == '' || urlInfoval == '请输入链接文字')
                urlInfoval = urlval;
            var buf = new StringBuilder();
            buf.append('<a title="').append(urlInfoval).append('" href="');
            buf.append(urlval).append('" rel="external">').append(urlInfoval).append('</a>');
            this.insertHTML(buf.toString());
            url.value = '';
            urlInfo.value = '';
        },
        
        /** 打开表情面板。*/
        facePanel: function(o) {
            this.beginSelection();
            var face_panel_id = this.panelId + o.id.replace(/tbr/i, '');
            var face_panel = $('#' + face_panel_id);
            var oPos = giant.dom.xy(o);
            var oSize = [o.offsetWidth, o.offsetHeight];
            var $self = this;
            if(face_panel.length == 0) {
                var buf = new StringBuilder();
                buf.append('<div class="edr-panel face-panel" id="').append(face_panel_id).append('" ');
                buf.append('style="display:none;">\n');
                var f = function() {
                    var fh = new StringBuilder();
                    fh.append('<ul>\n');
                    for(var i = 0, len = FACES.length; i < len; i++) {
                        fh.append('<li title="').append(FACES[i]).append('" onmouseover="this.className=\'hover\';" ');
                        fh.append('onmouseout="this.className=\'\';"><img alt="').append(FACES[i]).append('" title="');
                        fh.append(FACES[i]).append('" src="').append($self._facePath).append(i).append('.gif" ');
                        fh.append('onclick="GEditors[\'').append($self.container).append('\'].insertFace(this);" /></li>');
                    }
                    fh.append('</ul>\n');
                    $('#' + face_panel_id).html(fh.toString());
                };
                buf.append('<div class="clear"></div>\n');
                buf.append('</div>\n');
                $(buf.toString()).appendTo('body')[0];
                face_panel = $('#' + face_panel_id);
                this.togglePanel(o, face_panel, [oPos[0] + 5, oPos[1] + oSize[1] + 5], f);
            } else
                this.togglePanel(o, face_panel, [oPos[0] + 5, oPos[1] + oSize[1] + 5]);
        },
        
        /** 插入表情图片。*/
        insertFace: function(o) {
            if(o) {
                var shtml = new StringBuilder();
                shtml.append('<img alt="').append(o.alt || '').append('" title="');
                shtml.append(o.title || '').append('" src="').append(o.src).append('" ');
                shtml.append('onerror="ImageLoad(this, ImageLoad.DEFAULT_FACE);"/>');
                this.insertHTML(shtml.toString());
            }
        },
        
        _imageCurrTag: 'net',
        
        /** 图片面板标签事件。*/
        clickImagePanel: function(o, callback) {
            if($(o).hasClass('selected'))
                return;
            var tagsign = o.id.replace(/_tag/ig, '');
            $('#' + this._imageCurrTag + '_img_wrap').css('display', 'none');
            $('#' + this._imageCurrTag + '_tag').removeClass('selected');
            $(o).addClass('selected');
            $('#' + tagsign + '_img_wrap').css('display', 'block');
            this._imageCurrTag = tagsign;
            if(tagsign == 'net')
                $('#' + tagsign + '_img_wrap').find('input[name=netImageUrl]').focus();
            if(giant.isFunction(callback))
                callback.call(this);
        },
        
        /** 打开图片选择(上传)面板。*/
        imagePanel: function(o) {
            this.beginSelection();
            var img_panel_id = this.panelId + o.id.replace(/tbr/i, '');
            var img_panel = $('#' + img_panel_id);
            var oPos = giant.dom.xy(o);
            var oSize = [o.offsetWidth, o.offsetHeight];
            var $self = this;
            var f = function() {
                if($self._imageCurrTag == 'net')
                    $(this).find('input[name=netImageUrl]').focus();
            };
            if(img_panel.length == 0) {
                var buf = new StringBuilder();
                buf.append('<div class="edr-panel img-panel" id="').append(img_panel_id).append('" ');
                buf.append('style="display:none;">\n');
                buf.append('  <div class="menu"><ul>\n');
                buf.append('  <li class="net selected" id="net_tag" ');
                buf.append('onclick="GEditors[\'').append(this.container).append('\'].clickImagePanel(this);">网络图片</li>\n');
                if(this.canUploadImage) {
                    buf.append('  <li class="upload" id="upload_tag" ');
                    buf.append('onclick="GEditors[\'').append(this.container).append('\'].clickImagePanel(this, GEditors[\'');
                    buf.append(this.container).append('\'].localeImagePanel);">本地图片</li>\n');
                }
                buf.append('  <li class="album" id="album_tag" ');
                buf.append('onclick="GEditors[\'').append(this.container).append('\'].clickImagePanel(this, GEditors[\'');
                buf.append(this.container).append('\'].albumImagePanel);">相册图片</li>\n');
                buf.append('  <a href="javascript:void(0)" class="close" onclick="GEditors[\'').append(this.container);
                buf.append('\'].closeImagePanel(\'').append(img_panel_id).append('\');return false;">关闭×</a>\n');
                buf.append('  </ul></div>\n');
                buf.append('  <div class="edr-img-wrap" id="net_img_wrap">\n');
                buf.append('  <form id="form_net_image" name="formNetImage" method="post" action="').append(location.href).append('">\n');
                buf.append('  <table cellspacing="0">');
                buf.append('  <tr>');
                buf.append('    <td width="60" height="30" align="right">图片地址：</td>');
                buf.append('    <td width="210"><input type="text" class="txt w200" name="netImageUrl" value="http://" /></td>');
                buf.append('    <td width="70"><input type="button" class="btn btnmain" id="btn_img_preview" value="预&nbsp;&nbsp;览" onclick="GEditors[\'');
                buf.append(this.container).append('\'].previewNetImage(this, \'form_net_image\');" /></td>');
                buf.append('    <td width="70"><input type="button" class="btn btnmain" value="确&nbsp;&nbsp;定" onclick="GEditors[\'');
                buf.append(this.container).append('\'].insertNetImage(this, \'form_net_image\');" /></td>');
                buf.append('  </tr>');
                buf.append('  </table>');
                buf.append('  <div class="edr-img-preview" id="net_img_preview"></div>');
                buf.append('  <div class="edr-img-error pre" id="edr_img_error" style="display:none;"></div>');
                buf.append('  </form>\n');
                buf.append('  </div>\n');
                if(this.canUploadImage) {
                    buf.append('  <div class="edr-img-wrap" id="upload_img_wrap" style="display:none;"></div>');
                }
                buf.append('  <div class="edr-img-wrap" id="album_img_wrap" style="display:none;"></div>');
                buf.append('<div class="clear"></div>\n');
                buf.append('</div>\n');
                $(buf.toString()).appendTo('body')[0];
                img_panel = $('#' + img_panel_id);
                this.togglePanel(o, img_panel, [oPos[0] + 5, oPos[1] + oSize[1] + 5], f);
            } else
                this.togglePanel(o, img_panel, [oPos[0] + 5, oPos[1] + oSize[1] + 5], f);
        },
        
        /** 相册图片选择面板。*/
        albumImagePanel: function() {
            var albumWrap = $('#album_img_wrap');
            if(trim(albumWrap.html()) == '') {
                var buf = new StringBuilder();
                buf.append('<div class="album-wrap" id="edr_album_list">\n');
                buf.append('  <select id="cmb_album_list" name="userAlbumList" class="w150" onchange="GEditors[\'');
                buf.append(this.container).append('\'].getPhotoList(1);">');
                buf.append('    <option value="-1">正在加载相册列表...</option>');
                buf.append('  </select> <span id="info_loadalbums_status">请稍候......</span>');
                buf.append('</div>\n');
                buf.append('<div class="photo-wrap" id="edr_photo_list">\n');
                buf.append('</div>\n');
                buf.append('  <div class="vspdn">');
                buf.append('  <table width="100%" cellspacing="0">');
                buf.append('  <tr>');
                buf.append('    <td width="90" height="24">图片排列方式：</td>');
                buf.append('    <td width="16"><input type="radio" id="img_align_left" name="imageAlign" value="left" checked="checked" /></td>');
                buf.append('    <td width="40"><label for="img_align_left">居左</label></td>');
                buf.append('    <td width="16"><input type="radio" id="img_align_center" name="imageAlign" value="center" /></td>');
                buf.append('    <td width="40"><label for="img_align_center">居中</label></td>');
                buf.append('    <td width="16"><input type="radio" id="img_align_right" name="imageAlign" value="right" /></td>');
                buf.append('    <td width="40"><label for="img_align_right">居右</label></td>');
                buf.append('    <td align="right">');
                buf.append('<input type="button" class="btn btnmain w80" value="确&nbsp;&nbsp;定" onclick="GEditors[\'');
                buf.append(this.container).append('\'].insertAlbumImage();" />&nbsp;&nbsp;');
                buf.append('    </td>');
                buf.append('  </tr></table>');
                buf.append('  </div>'); 
                buf.append('<div class="clear">&nbsp;</div>');
                albumWrap.html(buf.toString());
                this._requestAlbumList(this.currentUid);
                this._requestPhotoList(this.currentUid, {albumId:0, editorId:this.container});
            }
        },
        
        /** 获得相册图片列表。*/
        getPhotoList: function(page) {
            var psc = 0;
            $('#edr_photo_list .photo-bd').each(function() {
                if($(this).hasClass('selected'))
                    psc++;
            });
            if(psc > 0) {
                var c = confirm('您已经选中了部份图片，翻页之前需要将这些图片插入编辑器中吗？', '是的', '再选其他的');
                if(c) {
                    this.insertAlbumImage();
                }
            }
            var params = {};
            params.albumId = $('#cmb_album_list').val();
            params.editorId = this.container;
            params.p = page;
            this._requestPhotoList(this.currentUid, params);
        },
        
        /** 插入相册图片。*/
        insertAlbumImage: function() {
            var align = $('input[name=imageAlign]:checked').val();
            var buf = new StringBuilder();
            $('#edr_photo_list .photo-bd').each(function() {
                if($(this).hasClass('selected'))
                    buf.append('<div class="edr-img" style="text-align:' + align + '">')
                            .append($(this).find('span').html()).append('</div>');
            });
            var imgs = buf.toString();
            if(imgs !== '') {
                this.insertHTML(buf.toString());
                $('#edr_photo_list .photo-bd').each(function() {
                    if($(this).hasClass('selected'))
                        $(this).removeClass('selected').find('p').remove();
                });
            }
        },
        
        // 请求服务器获得相册列表。
        _requestAlbumList: function(uid) {
            var params = new StringBuilder();
            params.append(this.albumImageURL).append('?uid=').append(uid).append('&jsoncallback=?');
            $.getJSON(params.toString());
        },
        
        // 请求服务器获得相片列表。
        _requestPhotoList: function(uid, params) {
            var buf = new StringBuilder();
            params['albumId'] = typeof params['albumId'] === 'undefined' ? 0 : params['albumId'];
            params['editorId'] = typeof params['editorId'] === 'undefined' ? this.container : params['editorId'];
            params['p'] = typeof params['p'] === 'undefined' ? 1 : params['p'];
            buf.append(this.photoImageURL).append('?uid=').append(uid);
            buf.append('&albumId=').append(params['albumId'].toString());
            buf.append('&editorId=').append(params['editorId']);
            if(params['p'] !== 1)
                buf.append('&p=').append(params['p'].toString());
            buf.append('&jsoncallback=?');
            $.getJSON(buf.toString());
        },
        
        /** 载入本地图片面板。*/
        localeImagePanel: function() {
            var updImgWrap = $('#upload_img_wrap');
            if(trim(updImgWrap.html()) == '') {
                var buf = new StringBuilder();
                buf.append('<form id="form_upload_image" name="formUploadImage" method="post" ');
                buf.append('action="').append(this.uploadImageURL).append('" enctype="multipart/form-data">');
                buf.append('<div class="uld-img-wrap">\n');
                buf.append('  <input type="text" class="txt w300" id="imageFile_value" />');
                buf.append('  <input type="button" class="btn btnmain w60" value="浏览..." />');
                buf.append('  <input type="file" class="file" size="50" name="imageFile" onchange="');
                buf.append('GEditors[\'').append(this.container).append('\'].previewUploadImage(this);" />');
                buf.append('</div>\n');
                buf.append('<div class="tcenter" id="div_upload_btn" style="display:none;"><input type="button" ');
                buf.append('class="btn btnmain w100" value="&nbsp;开始上传&nbsp;" /></div>');
                buf.append('<div class="edr-img-preview" id="upd_img_preview"></div>');
                buf.append('</form>');
                updImgWrap.html(buf.toString());
            }
        },
        
        /** 关闭图片面板。*/
        closeImagePanel: function(id) {
            try {
                $('#form_net_image').resetForm();
                $('#form_upload_image').resetForm();
                $('#net_img_preview').html('');
                $('#upd_img_preview').html('');
                $('#div_upload_btn').hide('fast');
            } catch(e) {}
            $('#' + id).hide('fast');
            $('#tbr' + id.replace(new RegExp(this.panelId), '')).removeClass('selected');
        },
        
        /** 预览要上传的图片。<strong>该功能不支持Firefox浏览器。</strong>*/
        previewUploadImage: function(o) {
            var url = o.value;
            if(!url.endsWith(".jpg") && !url.endsWith(".png") && !url.endsWith(".gif")) {
                alert("目前只支持上传 jpg、gif和 png格式的图片。请重新选择图片！");
                $('#div_upload_btn').hide('fast');
                o.value = '';
                return;
            }
            var pid = '#upd_img_preview';
            var nsize = [0, 0];
            $('#imageFile_value').val(url);
            $('#div_upload_btn').show('fast');
            if(B.msie && B.version < 8) {
                var newImg = $('<img alt="" src="' + url + '" />');
                $(pid).html(newImg);
                this._loadImage($(pid).find('img'));
            } else {
                $(pid).html('您使用的浏览器不支持即时预览图片功能，不妨换成IE试试。');
            }
        },
        
        /** 插入网络图片。*/
        insertNetImage: function(o, formId) {
            var form = $('#' + formId);
            this.previewNetImage(giant.E('btn_img_preview'), formId);
            var img = $('#net_img_preview img');
            var shtml = '<img onerror="ImageLoad(this, ImageLoad.DEFAULT_IMAGE);" src="' + img.attr('src') + '" />';
            this.insertHTML(shtml);
            form[0].netImageUrl.value = '';
            $('#net_img_preview').html('');
        },
        
        /** 预览网络图片。*/
        previewNetImage: function(o, formId) {
            $(o).attr('disabled', 'disabled');
            var form = $('#' + formId);
            var imgurl = trim(form[0].netImageUrl.value);
            var imgarr = imgurl.split('.');
            var imgext = imgarr[imgarr.length - 1].toLowerCase();
            if(imgurl == 'http://' || imgurl == '' || imgarr.length <= 1 || 
                    (imgext != 'jpg' && imgext != 'png' && imgext != 'gif')) {
                alert('请输入要插入的网络图片地址！目前只支持jpg/jpeg、gif、png格式的图片！');
                form[0].netImageUrl.focus();
                $(o).removeAttr('disabled');
                return;
            }
            var imgstr = new StringBuilder();
            imgstr.append('<img alt="" src="').append(imgurl).append('" ');
            if(B.msie) {
                imgstr.append('onreadystatechange="');
            } else {
                imgstr.append('onload="');
            }
            imgstr.append('ImageLoading(this, GEditors[\'').append(this.container);
            imgstr.append('\']._loadImage);" onerror="ImageLoad(this, ImageLoad.DEFAULT_IMAGE);" />');
            $('#net_img_preview').html(imgstr.toString());
            $(o).removeAttr('disabled');
            form = null, imgurl = null, imgarr = null, imgext = null;
        },
        
        _loadImage: function(o) {
            if(o) {
                var w = o.width(), h = o.height(), iw = 0, ih = 0;
                if(w > h) { // 横向图片
                    if(w >= 420) {
                        iw = 420;
                        ih = parseInt(iw * h / w);
                        o.width(iw);
                    }
                } else { // 纵向图片
                    if(h > 420) {
                        ih = 420;
                        iw = parseInt(w * ih / h);
                        o.width(iw == 0 ? 1 : iw);
                    }
                }
            }
        }
    };
    
})(giant, jQuery);